﻿package daphne.noterun.notes
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import daphne.noterun.objects.GameObject;
	import daphne.noterun.menus.Room;
	import daphne.noterun.objects.Note;
	import daphne.noterun.objects.Coin;
	
	public class PlatformGenerator extends MovieClip
	{
		public static const NUM_MIDI_NOTES:int = 128;
		private static const MIN_FRAMES_BETWEEN_COIN_DROPS = 50;
		
		var tracks:Vector.<NoteTrack>;
		
		var lastThreeNotes:Vector.<Note>;
		var framesSinceLastCoinDrop:int;
		
		private var room:Room;
		
		public function PlatformGenerator(room:Room)
		{
			super();
			this.room = room;
			this.framesSinceLastCoinDrop = MIN_FRAMES_BETWEEN_COIN_DROPS;
			
			lastThreeNotes = new Vector.<Note>();
			lastThreeNotes.push(null, null, null);
			
			//notes should be fixed length
			tracks = new Vector.<NoteTrack>(NUM_MIDI_NOTES, true);
			var i:int;
			for (i = 0; i < NUM_MIDI_NOTES; i++)
			{
				tracks[i] = new NoteTrack(room, i);
			}
		}
		
		public function noteOn(midiNumber:int)
		{
			var newNote:Note = tracks[midiNumber].startNote();
			this.addChild(newNote);
		}
		
		public function noteOff(midiNumber:int)
		{
			var note:Note = tracks[midiNumber].stopNote();
			
			updateHistory(note);
			addCoinIfNeeded(note)
		}
		
		public function update():void
		{
			var track:NoteTrack;
			for each (track in tracks) {
				var toRemove:Array = track.update();
				var item:GameObject;
				for each (item in toRemove) {
					this.removeChild(item);
				}
			}
			
			framesSinceLastCoinDrop++;
		}
		
		public function stopMovement():void
		{
			var track:NoteTrack;
			for each (track in tracks) {
				track.stopMovement();
			}
		}
		
		public function getNotesInTrack(noteNum:int):Array {
			return tracks[noteNum].getNoteObjects();
		}
		
		/**
		 * Coins only appear at peaks (the notes on left and right are of
		 * lower pitch), and only appear with at least a certain delay between
		 * them.
		 * @param	note The note to possibly add the coin over
		 */
		private function addCoinIfNeeded(note:Note)
		{
			if (
			framesSinceLastCoinDrop > MIN_FRAMES_BETWEEN_COIN_DROPS &&
			lastThreeNotes.length >= 3 &&
			lastThreeNotes[0] != null && 
			lastThreeNotes[1] != null && 
			lastThreeNotes[2] != null &&
			0 < 1 < 2 &&
			lastThreeNotes[0].noteNumber < lastThreeNotes[1].noteNumber &&
			lastThreeNotes[2].noteNumber < lastThreeNotes[1].noteNumber )
			{
				framesSinceLastCoinDrop = 0;
				
				var topNote:Note = lastThreeNotes[1];
				room.coinContainer.addCoinOverNote(topNote);
				
				//clear the history
				var i:int;
				for (i = 0; i < this.lastThreeNotes.length; i++)
					this.lastThreeNotes[i] = null;
			}
			
		}
		
		private function updateHistory(note:Note)
		{
			lastThreeNotes.push(note);
			lastThreeNotes.shift();
		}
	}
}